// vertex shader
// transform sceletal model

#define quat	vec4

uniform samplerBuffer	unJointData;			// RGBA32F : quat (4), pos (3), empty (1)
uniform samplerBuffer	unWeightData;			// RGB32F  : pos (3), joint index (1), bias (1), empty (1)
uniform int				unJointIndexOffset  = 0;
uniform int				unWeightIndexOffset = 0;

layout(location = 0) in vec2	inTexcoord;
layout(location = 1) in ivec2	inWeight;		// start index, count


out	TVertexData {
	vec4	vPosition;
	vec2	vTexcoord;
} Output;


vec3 RotateVec(in quat qleft, in vec3 vright)
{
	vec3	uv, uuv, qvec( qleft );
	
	uv	= cross( qvec, vright );
	uuv	= cross( qvec, uv );
	uv	*= 2.0 * qleft.w;
	uuv	*= 2.0;
	
	return vright + uv + uuv;
}


void main()
{
	vec3	position = vec3(0.0);
	
	for (int i = 0; i < inWeight[1]; ++i)
	{
		int		idx		= ( inWeight[0] + i + unWeightIndexOffset ) * 2;
		
		// read weight data
		vec3	w_pos	= texelFetch( unWeightData, idx + 0 ).rgb;
		vec3	w_data	= texelFetch( unWeightData, idx + 1 ).rgb;
		int		joint	= int( w_data.x );
		float	bias	= w_data.y;
		
		idx = ( joint + unJointIndexOffset ) * 2;
		
		// read joint data
		vec4	orient	= texelFetch( unJointData, idx + 0 ).rgba;
		vec3	j_pos	= texelFetch( unJointData, idx + 1 ).rgb;
		
		position += ( j_pos + RotateVec( orient, w_pos ) ) * bias;
	}
	
	
	Output.vTexcoord = inTexcoord;
	Output.vPosition = vec4( position, 1.0 );
}